#include "disp_proc.h"
#include <stdint.h>
#include "esp32_oled.hpp"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/timers.h"
#include <cstring>
typedef struct {
    uint8_t nextCMD;
    uint8_t lastCMD;
} oledFunc_t;

static u8g2_t u8g2;
static u8g2_t *pu8g2 = &u8g2;
static BaseType_t oledTaskID = 0;
static TimerHandle_t oledTimer = NULL;
static QueueHandle_t oledQueue = NULL;
static oledFunc_t oledFunc;


#define OLED_TIMER_PERIOD 1000
#define OLED_CLOSE_TIME 180

static void oledTimerCallback(TimerHandle_t xTimer)
{
    if (oledFunc.nextCMD != oledFunc.lastCMD) {
        oledDisplay(oledFunc.nextCMD, NULL, 0);
        oledFunc.lastCMD = oledFunc.nextCMD;
    }
}

static void oledTask(void *pvParameters)
{
    oledSpiInit();
    oledReset();
    u8g2Init(pu8g2);
    oledMsg_t oledMsg;
    BaseType_t err = 0;
    BaseType_t count = 0;
    while (1) {
        // 计时三分钟未收到数据则关闭显示
        err = xQueueReceive(oledQueue, &oledMsg, pdMS_TO_TICKS(1000));
        if (err == pdFALSE) {
            oledMsg.cmd = OLED_CMD_NULL;
            count++;
            if (count >= OLED_CLOSE_TIME) {
                oledMsg.cmd = OLED_CMD_CLOSE;
            }
        }
        switch (oledMsg.cmd)
        {
        case OLED_CMD_MAIN:
            /* code */
            break;
        case OLED_CMD_TRIAXIAL:
            /* code */
            break;
        case OLED_CMD_WEATHER:
            /* code */
            break;
        case OLED_CMD_TIME:
            /* code */
            break;
        case OLED_CMD_NETWORK:
            /* code */
            break;
        case OELD_CMD_BATTERY:
            /* code */
            break;
        case OLED_CMD_CLOSE:
            /* code */
            break;
        
        default:
            break;
        }

        if (oledMsg.data != NULL) {
            vPortFree(oledMsg.data);
            oledMsg.data = NULL;
        }

    }
}

int oled_init(void)
{
    // 创建一个队列，用于接收显示数据
    oledQueue = xQueueCreate(10, sizeof(oledMsg_t));
    // 创建一个定时器，用于定时发送刷新命令
    oledTimer = xTimerCreate("oledTimer", pdMS_TO_TICKS(1000), pdTRUE, NULL, oledTimerCallback);
    // 创建一个任务，用于显示刷新
    oledTaskID = xTaskCreate(oledTask, "oledTask", 2048, NULL, 5, NULL);
    return 0;
}


int oledDisplay(uint8_t cmd, uint8_t *data, uint16_t len)
{
    oledMsg_t oledMsg;
    oledMsg.cmd = cmd;
    oledMsg.data = (uint8_t *)pvPortMalloc(len);
    memcpy(oledMsg.data, data, len);
    oledMsg.len = len;
    oledFunc.nextCMD = cmd;
    xQueueSend(oledQueue, &oledMsg, 0);
    return 0;
}

